import { Nullable, dynamicValue, makeResult, Result } from 'vest-utils';
import { TIsolate, Walker } from 'vestjs-runtime';

import { useInclusion } from '../../core/context/SuiteContext';
import { TIsolateTest } from '../../core/isolate/IsolateTest/IsolateTest';
import { VestTest } from '../../core/isolate/IsolateTest/VestTest';
import { useIsExcludedIndividually } from '../../isolates/skipWhen';

import { FocusSelectors, TIsolateFocused } from './focused';
import { useHasOnliedTests } from './useHasOnliedTests';
//Checks whether a certain test profile excluded by any of the exclusion groups.

function useClosestMatchingFocus(
  testObject: TIsolateTest,
): Result<Nullable<TIsolateFocused>> {
  return makeResult.Ok(
    Walker.findClosest(testObject, (child: TIsolate) => {
      if (!FocusSelectors.isIsolateFocused(child)) return false;

      const { fieldName } = VestTest.getData(testObject);

      return child.data.match?.includes(fieldName) || child.data.matchAll;
    }),
  );
}

export function useIsExcluded(testObject: TIsolateTest): boolean {
  const { fieldName } = VestTest.getData(testObject);

  if (useIsExcludedIndividually()) return true;
  const inclusion = useInclusion();
  const focusMatch = useClosestMatchingFocus(testObject).unwrap();
  // if test is skipped
  // no need to proceed
  if (FocusSelectors.isSkipFocused(focusMatch).unwrap()) return true;
  const isTestIncluded = FocusSelectors.isOnlyFocused(focusMatch).unwrap();
  // if field is only'ed
  if (isTestIncluded) return false;

  // If there is _ANY_ `only`ed test (and we already know this one isn't) return true
  if (useHasOnliedTests(testObject)) {
    // Check if inclusion rules for this field (`include` hook)
    return !dynamicValue(inclusion[fieldName], testObject);
  }

  // We're done here. This field is not excluded
  return false;
}
